﻿#define _CRT_SECURE_NO_WARNINGS

//C / C++程序内存分配的⼏个区域：
//1. 栈区（stack）：在执⾏函数时，函数内局部变量的存储单元都可以在栈上创建，函数执⾏结束时
//这些存储单元⾃动被释放。栈内存分配运算内置于处理器的指令集中，效率很⾼，但是分配的内
//存容量有限。栈区主要存放运⾏函数⽽分配的局部变量、函数参数、返回数据、返回地址等。
//2. 堆区（heap）：⼀般由程序员分配释放，若程序员不释放，程序结束时可能由OS回收。分配⽅
//式类似于链表。
//3. 数据段（静态区）（static）存放全局变量、静态数据。程序结束后由系统释放。
//4. 代码段：存放函数体（类成员函数和全局函数）的⼆进制代码。

//#include<stdio.h>
//int main()
//{
//	int a = 10000;                  
//	FILE* pf = fopen("test.txt", "wb");
//	fwrite(&a, 4, 1, pf);//以二进制的形式写入文件
//	fclose(pf);
//	pf = NULL;
//	return 0;
//}
//我们程序的数据需要输出到各种外部设备，也需要从外部设备获取数据，不同的外部设备的输⼊输出
//操作各不相同，为了⽅便程序员对各种设备进⾏⽅便的操作，我们抽象出了流的概念，我们可以把流
//想象成流淌着字符的河。
//C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的。
//⼀般情况下，我们要想向流⾥写数据，或者从流中读取数据，都是要打开流，然后操作。
//C语⾔程序在启动的时候，默认打开了3个流：
//• stdin - 标准输⼊流，在⼤多数的环境中从键盘输⼊，scanf函数就是从标准输⼊流中读取数据。
//• stdout - 标准输出流，⼤多数的环境中输出⾄显⽰器界⾯，printf函数就是将信息输出到标准输出
//流中。
//• stderr - 标准错误流，⼤多数环境中输出到显⽰器界⾯。
//这是默认打开了这三个流，我们使⽤scanf、printf等函数就可以直接进⾏输⼊输出操作的。
//stdin、stdout、stderr三个流的类型是： FILE * ，通常称为⽂件指针。
//C语⾔中，就是通过 FILE * 的⽂件指针来维护流的各种操作的。
//⽂件在读写之前应该先打开⽂件，在使⽤结束之后应该关闭⽂件。
//在编写程序的时候，在打开⽂件的同时，都会返回⼀个FILE* 的指针变量指向该⽂件，也相当于建⽴了
//指针和⽂件的关系。
//ANSIC规定使⽤ fopen 函数来打开⽂件， fclose 来关闭⽂件。
//#include<stdio.h>
////操作文件
//int main()
//{
//	//打开文件，只写
//	//若打开失败，返回NULL
//	FILE* pf = fopen("data.txt", "r");
//	//判断
//	if (pf == NULL)
//	{
//		perror("fopen");//报出错误信息
//		return 1;
//	}
//	//读文件
//	//读取第一个字符
//	int ch = fgetc(pf);
//	printf("%c\n", ch);
//	//读取第二个字符
//	ch = fgetc(pf);
//	printf("%c\n", ch);
//	//读取第三个字符
//	ch = fgetc(pf);
//	printf("%c\n", ch);
//	//写文件
//	//写入26个字母
//	//for (int i = 0; i < 26; i++)
//	//{
//	//	fputc('a' + i , pf);
//	//	fputc(' ', pf);//每个字母后加个空格
//	//}
//
//	////逐个字母写入
//	//fputc('a', pf);
//	//fputc('c', pf);
//	//fputc('d', pf);
//	//fputc('b', pf);
//	
//	//关闭文件
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}
//.表示当前目录
//..表示上一级路径
// 没写.表示默认当前路径


////文件拷贝
////写一个代码，完成将data1.txt文件的内容 拷贝一份生成data2.txt
//#include<stdio.h>
//int main()
//{
//	FILE* pfread = fopen("data1.txt", "r");
//	if (pfread == NULL)
//	{
//		perror("fopen->data1.txt");
//		return 1;
//	}
//	FILE* pfwrite = fopen("data2.txt", "w");
//	if (pfwrite == NULL)
//	{
//		fclose(pfread);//判断为真后，要将pfread置为空指针
//		pfread = NULL;
//		perror("fopen->data2.txt");
//		return 1;
//	}
//	//数据的读写（拷贝）
//	int ch = 0;
//	//每读一个字符就放入ch中，直到读完为止
//	while ((ch = fgetc(pfread)) != EOF)
//	{
//		fputc(ch, pfwrite);//写入data2.txt文件中
//	}
	//fclose(pfread);
	//fclose(pfwrite);
//	return 0;
//}
//#include<stdio.h>
//int main()
//{
//	FILE* pf = fopen("data.txt", "w");
//	if (pf == NULL)
//	{
//		perror("fopen->data.txt");
//		return 1;
//	}
//	//写文件  写一行
//	fputs("abcdef\n", pf);
//	fputs("abcdef\n", pf);
//	fputs("abcdef\n", pf);
//
//	fclose(pf);
//	pf = NULL;
//
//}
//#include<stdio.h>
//int main()
//{
//	FILE* pf = fopen("data.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen->data.txt");
//		return 1;
//	}
//	//读一行
//	//最多读num-1个字符，第num个字符放\0
//	char arr[20] = "xxxxxxxxxxxxx";
//	fgets(arr, 10, pf);
//
//	fclose(pf);
//	pf = NULL;
//
//}
//#include<stdio.h>
//int main()
//{
//	FILE* pf = fopen("data.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen->data.txt");
//		return 1;
//	}
//	//也可以读键盘上的字符，再打印在屏幕上
//	char arr[20] = "xxxxxxxxxxxxx";
//	fgets(arr, 10, stdin);
//	fputs(arr, stdout);
//
//	fclose(pf);
//	pf = NULL;
//}
//格式化打印在文件上
//struct Stu
//{
//	char name[20];
//	int age;
//	float score;
//};
//
//#include<stdio.h>
//int main()
//{
//	struct Stu s = { "zhangsan",20,100.0f };
//	FILE* pf = fopen("data.txt", "w");
//	if (pf == NULL)
//	{
//		perror("fopen->data.txt");
//		return 1;
//	}
//	//写文件
//	fprintf(pf, "%s %d %lf", s.name, s.age, s.score);
//	fclose(pf);
//	pf = NULL;
//}
//struct Stu
//{
//	char name[20];
//	int age;
//	float score;
//};
//
//#include<stdio.h>
//int main()
//{
//	struct Stu s = { 0};
//	FILE* pf = fopen("data.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen->data.txt");
//		return 1;
//	}
//	//读写文件
//	fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));
//	//stdout表示打印在屏幕上
//	fprintf(stdout, "%s %d %lf", s.name, s.age, s.score);
//	fclose(pf);
//	pf = NULL;
//}
//struct Stu
//{
//	char name[20];
//	int age;
//	float score;
//};
//
//#include<stdio.h>
//int main()
//{
//	struct Stu s = { "zhangsan",20,100.0f };
//	FILE* pf = fopen("data.txt", "wb");
//	if (pf == NULL)
//	{
//		perror("fopen->data.txt");
//		return 1;
//	}
//	//fwrite 以二进制形式写文件
//	//数据地址，数据大小（单位：字节），写入N个数据，文件指针 
//	fwrite(&s, sizeof(s), 1, pf);
//	fclose(pf);
//	pf = NULL;
//}
//struct Stu
//{
//	char name[20];
//	int age;
//	float score;
//};
//
//#include<stdio.h>
//int main()
//{
//	struct Stu s = { 0 };
//	FILE* pf = fopen("data.txt", "rb");
//	if (pf == NULL)
//	{
//		perror("fopen->data.txt");
//		return 1;
//	}
//	//fread 以二进制形式读文件
//	//数据地址，数据大小（单位：字节），写入N个数据，文件指针 
//	fread(&s, sizeof(s), 1, pf);
//
//	printf("%s %d %.1lf", s.name, s.age, s.score);
//	fclose(pf);
//	pf = NULL;
//}
//sprintf函数
//将格式化数据转换成字符串
//#include<stdio.h>
//struct Stu
//{
//	char name[20];
//	int age;
//	float score;
//};
//
//int main()
//{
//	struct Stu s = { "zhangsan",20,99.5f };
//	char arr[100] = { 0 };
//	//arr是写入目标文件的地址
//	sprintf(arr, "%s %d %.1lf", s.name, s.age, s.score);//将结构体内的标准化数据写入arr中
//	//printf("%s", arr);
//	//sscanf函数 读取字符串并放入标准化数据中
//	struct Stu tmp = { 0 };
//	sscanf(arr, "%s %d %f", tmp.name, &(tmp.age), &(tmp.score));
//	printf("%s %d %.1lf", tmp.name, tmp.age, tmp.score);
//	return 0;
//}

//scanf与printf
// scanf针对标准输入（键盘）的格式化输入函数
// printf 针对标准输出（屏幕）的格式化输出函数
// fscanf针对所有输入流的格式化输入的函数
// fprintf 针对所有输出流的格式化输出的函数
// sscanf 从一个字符串读取一个格式化的数据
// sprintf 把一个格式化的数据转换成字符串
#include <stdio.h>
#include<stdlib.h>
struct st
{
	int a;
	int* arr;
};
int main()
{//用结构体指针变量ps接收malloc函数分配空间的地址
	struct st* ps = (struct st*)malloc(sizeof(struct st));
	//判断
	if (ps == NULL)
	{
		return 1;
	}
	//使用
	ps->a = 100;
	//再次使用malloc函数给数组arr开辟空间
	ps->arr = (int*)malloc(10 * sizeof(int));
	if (ps->arr == NULL)
	{
		perror("malloc-2");
		return 1;
	}
	//使用
	for (int i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	//数组空间不够
	// 利用realloc函数扩大
	int* ptr = (int*)realloc(ps->arr, 15 * sizeof(int));
	if (ptr == NULL)
	{
		perror("realloc");
		return 1;
	}
	else
	{
		ps->arr = ptr;
	}
	//初始化前15个元素
	for (int i = 0; i < 15; i++)
	{
		ps->arr[i] = i;
	}
	
	//打印
	for (int i = 0; i < 15; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	//释放
	free(ps->arr);
	ps->arr = NULL;
	free(ps);
	ps = NULL;
	return 0;
}